﻿using System;
using System.Configuration;
using System.IO;
using System.Reflection;

namespace KyuuBackground
{
    static class KyuuBackgroundConfigurationManager
    {
        private static Type smSectionType = typeof(KyuuBackgroundConfigurationSection);
        private static string smSectionFullName = smSectionType.FullName;
        internal static string SettingsBase { get; private set; }
        private static Configuration smConfig;
        internal static KyuuBackgroundConfigurationSection Section { get; private set; }

        private const string SectionName = "kyuuBackground";
        private const string UserConfigFilename = "User.config";
        private static FileSystemWatcher smConfigurationWatcher;

        static KyuuBackgroundConfigurationManager()
        {
            InitializeConfiguration();
        }

        internal static event EventHandler ConfigurationUpdated;

        private static void InitializeConfiguration()
        {
            SettingsBase = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "KyuuBackground");
            Directory.CreateDirectory(SettingsBase);

            AppDomain.CurrentDomain.TypeResolve += CurrentDomain_TypeResolve;

            smConfigurationWatcher = new FileSystemWatcher(SettingsBase, UserConfigFilename);
            smConfigurationWatcher.Changed += ConfigWatcher_Changed;
            smConfigurationWatcher.Renamed += ConfigWatcher_Changed;
            smConfigurationWatcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName;
            smConfigurationWatcher.EnableRaisingEvents = true;

            RefreshConfiguration();
        }

        private static void RefreshConfiguration()
        {
            try
            {
                smConfig = ConfigurationManager.OpenMappedExeConfiguration(new ExeConfigurationFileMap
                {
                    ExeConfigFilename = Path.Combine(SettingsBase, "KyuuBackground45.config"),
                    RoamingUserConfigFilename = Path.Combine(SettingsBase, UserConfigFilename),
                }, ConfigurationUserLevel.PerUserRoaming);

                Section = (KyuuBackgroundConfigurationSection)smConfig.Sections[SectionName];

                if (Section == null)
                {
                    Section = new KyuuBackgroundConfigurationSection();
                    Section.Picture.Source = "Your-Background-Goes-Here.png";

                    var sectionInfo = Section.SectionInformation;
                    sectionInfo.Type = smSectionFullName;
                    sectionInfo.AllowExeDefinition = ConfigurationAllowExeDefinition.MachineToRoamingUser; // or you won't be able to save

                    smConfig.Sections.Add(SectionName, Section);
                    smConfig.Save(ConfigurationSaveMode.Full); // or you lose the default values
                }
            }
            catch { }
        }

        private static void ConfigWatcher_Changed(object sender, FileSystemEventArgs e)
        {
            if (e.Name != UserConfigFilename)
                return;

            RefreshConfiguration();

            var handler = ConfigurationUpdated;
            if (handler != null)
                handler(sender, new EventArgs());
        }

        private static Assembly CurrentDomain_TypeResolve(object sender, ResolveEventArgs args)
        {
            if (args.Name == smSectionFullName)
            {
                return smSectionType.Assembly;
            }
            return null;
        }

        internal static void Save()
        {
            smConfig.Save();
        }
    }
}
